<template>
  <AvicModal
    :visible="true"
    title="cron表达式"
    :centered="true"
    width="640px"
    :body-style="{ height: '380px', 'overflow-x': 'hidden', 'overflow-y': 'scroll' }"
    @cancel="hidePopup"
  >
    <div>
      <a-tabs type="card" style="overflow: auto">
        <a-tab-pane v-if="shouldHide('second')" tab="秒">
          <CrontabSecond ref="cronsecond" :check="checkNumber" :cron="crontabValueObj" @update="updateCrontabValue" />
        </a-tab-pane>

        <a-tab-pane v-if="shouldHide('min')" tab="分钟" force-render>
          <CrontabMin ref="cronmin" :check="checkNumber" :cron="crontabValueObj" @update="updateCrontabValue" />
        </a-tab-pane>

        <a-tab-pane v-if="shouldHide('hour')" tab="小时" force-render>
          <CrontabHour ref="cronhour" :check="checkNumber" :cron="crontabValueObj" @update="updateCrontabValue" />
        </a-tab-pane>

        <a-tab-pane v-if="shouldHide('day')" tab="日" force-render>
          <CrontabDay ref="cronday" :check="checkNumber" :cron="crontabValueObj" @update="updateCrontabValue" />
        </a-tab-pane>

        <a-tab-pane v-if="shouldHide('month')" tab="月" force-render>
          <CrontabMonth ref="cronmonth" :check="checkNumber" :cron="crontabValueObj" @update="updateCrontabValue" />
        </a-tab-pane>

        <a-tab-pane v-if="shouldHide('week')" tab="周" force-render>
          <CrontabWeek ref="cronweek" :check="checkNumber" :cron="crontabValueObj" @update="updateCrontabValue" />
        </a-tab-pane>

        <a-tab-pane v-if="shouldHide('year')" tab="年" force-render>
          <CrontabYear ref="cronyear" :check="checkNumber" :cron="crontabValueObj" @update="updateCrontabValue" />
        </a-tab-pane>
      </a-tabs>

      <div class="popup-main">
        <div class="popup-result">
          <p class="title">时间表达式</p>
          <table>
            <thead>
              <th v-for="item of tabTitles" :key="item">{{ item }}</th>
              <th>Cron 表达式</th>
            </thead>
            <tbody>
              <td>
                <span v-if="crontabValueObj.second.length < 10" :title="crontabValueObj.second">
                  {{ crontabValueObj.second }}
                </span>
              </td>
              <td>
                <span v-if="crontabValueObj.min.length < 10" :title="crontabValueObj.min">
                  {{ crontabValueObj.min }}
                </span>
              </td>
              <td>
                <span v-if="crontabValueObj.hour.length < 10" :title="crontabValueObj.hour">
                  {{ crontabValueObj.hour }}
                </span>
              </td>
              <td>
                <span v-if="crontabValueObj.day.length < 10" :title="crontabValueObj.day">
                  {{ crontabValueObj.day }}
                </span>
              </td>
              <td>
                <span v-if="crontabValueObj.month.length < 10" :title="crontabValueObj.month">
                  {{ crontabValueObj.month }}
                </span>
              </td>
              <td>
                <span v-if="crontabValueObj.week.length < 10" :title="crontabValueObj.week">
                  {{ crontabValueObj.week }}
                </span>
              </td>
              <td>
                <span v-if="crontabValueObj.year.length < 10" :title="crontabValueObj.year">
                  {{ crontabValueObj.year }}
                </span>
              </td>
              <td class="result">
                <span v-if="crontabValueString.length < 90" :title="crontabValueString">{{ crontabValueString }}</span>
              </td>
            </tbody>
          </table>
        </div>
        <CrontabResult :ex="crontabValueString" />
      </div>
    </div>
    <template #footer>
      <a-button title="确定" type="primary" @click="submitFill">确定</a-button>
      <a-button title="重置" type="primary" ghost @click="clearCron">重置</a-button>
      <a-button title="取消" type="primary" ghost @click="hidePopup">取消</a-button>
    </template>
  </AvicModal>
</template>

<script setup>
import CrontabSecond from './second.vue';
import CrontabMin from './min.vue';
import CrontabHour from './hour.vue';
import CrontabDay from './day.vue';
import CrontabMonth from './month.vue';
import CrontabWeek from './week.vue';
import CrontabYear from './year.vue';
import CrontabResult from './result.vue';
const emit = defineEmits(['hide', 'fill']);
const { proxy } = getCurrentInstance();
const props = defineProps({
  /** 需要隐藏的规则配置页签，可选时间维度：second, min, hour, day, month, week, year */
  hideComponent: {
    type: Array,
    default: () => []
  },
  /** 传入的cron表达式 */
  expression: {
    type: String,
    default: ''
  }
});
const tabTitles = ref(['秒', '分钟', '小时', '日', '月', '周', '年']);
const hideComponent = ref([]);
const expression = ref('');
const crontabValueObj = ref({
  second: '*',
  min: '*',
  hour: '*',
  day: '*',
  month: '*',
  week: '?',
  year: ''
});
const crontabValueString = computed(() => {
  const obj = crontabValueObj.value;
  return `${obj.second} ${obj.min} ${obj.hour} ${obj.day} ${obj.month} ${obj.week}${
    obj.year === '' ? '' : ` ${obj.year}`
  }`;
});
onMounted(() => {
  expression.value = props.expression;
  hideComponent.value = props.hideComponent;
});
watch(expression, () =>
  proxy.$nextTick(() => {
    resolveExp();
  })
);
/**
 * 是否隐藏规则配置页签
 * @param {String} key 页签名称
 * @returns Boolean true:不隐藏；false:隐藏
 */
function shouldHide(key) {
  return !(hideComponent.value && hideComponent.value.includes(key));
}
/** 反解析表达式 */
function resolveExp() {
  // 反解析 表达式
  if (expression.value) {
    const arr = expression.value.split(/\s+/);
    if (arr.length >= 6) {
      // 6 位以上是合法表达式
      const obj = {
        second: arr[0],
        min: arr[1],
        hour: arr[2],
        day: arr[3],
        month: arr[4],
        week: arr[5],
        year: arr[6] ? arr[6] : ''
      };
      // crontabValueObj.value = {
      //   ...obj
      // };
      crontabValueObj.value = proxy.$lodash.cloneDeep(obj);
    }
  } else {
    // 没有传入的表达式 则还原
    clearCron();
  }
}
/**
 * 由子组件触发，更改表达式组成的字段值
 * @param {String} name  字段名
 * @param {String} value 字段值
 */
function updateCrontabValue(name, value) {
  crontabValueObj.value[name] = value;
}
/**
 * 表单选项的子组件校验数字格式（通过-props传递）
 * @param {Number} value 传入的值
 * @param {Number} minLimit 最小值
 * @param {Number} maxLimit 最大值
 * @returns Number 校验后的值
 */
function checkNumber(value, minLimit, maxLimit) {
  // 检查必须为整数
  let val = Math.floor(value);
  if (val < minLimit) {
    val = minLimit;
  } else if (value > maxLimit) {
    val = maxLimit;
  }
  return val;
}
/** 隐藏弹窗 */
function hidePopup() {
  emit('hide');
}
/** 填充表达式 */
function submitFill() {
  emit('fill', crontabValueString.value);
  hidePopup();
}
/** 还原选择项 */
function clearCron() {
  crontabValueObj.value = {
    second: '*',
    min: '*',
    hour: '*',
    day: '*',
    month: '*',
    week: '?',
    year: ''
  };
}
</script>

<style lang="less" scoped>
.popup-main {
  position: relative;
  margin: 10px auto;
  background: #fff;
  border-radius: 5px;
  font-size: 12px;
  overflow: hidden;
}
.popup-title {
  overflow: hidden;
  line-height: 34px;
  padding-top: 6px;
  background: #f2f2f2;
}
.popup-result {
  box-sizing: border-box;
  line-height: 24px;
  margin: 25px auto;
  padding: 15px 10px 10px;
  border: 1px solid #ccc;
  position: relative;
}
.popup-result .title {
  position: absolute;
  top: -14px;
  left: 50%;
  width: 140px;
  font-size: 14px;
  margin-left: -70px;
  text-align: center;
  line-height: 30px;
  background: #fff;
}
.popup-result table {
  text-align: center;
  width: 100%;
  margin: 0 auto;
}
.popup-result table td:not(.result) {
  width: 3.5rem;
  min-width: 3.5rem;
  max-width: 3.5rem;
}
.popup-result table span {
  display: block;
  width: 100%;
  font-family: arial;
  line-height: 30px;
  height: 30px;
  white-space: nowrap;
  overflow: hidden;
  border: 1px solid #e8e8e8;
}
.popup-result-scroll {
  font-size: 12px;
  line-height: 24px;
  height: 10em;
  overflow-y: auto;
}
</style>
